iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
自我挑戰組

從0到有學習JavaScript系列 第 15

第三章 型別、值和變數-問題筆記 RegExp part2

  • 分享至 

  • xImage
  •  

問題一、什麼是正規表達式?

  1. 正規表達式 (Regular Expression)用來描述文字字串中的模式(pattern)並進行比對 (match)。簡寫為RegExp。RegExp常被用來進行文字的處理。
  2. 成對的斜線\\ 構成正規表達式的字面值。第二條反斜線,後來還可以加上一個或多個字母(flags),會修改這個正規表達式模式(pattern)的意義。

問題二、RegExp 和regex差別在哪裡?
RegExp 和 regex 是不同的。
RegExp 是JavaScript中的一个内置對象,表示正規表達式。可以使用 RegExp 構造函數来創建正規表達式對象。例如:

const regex = new RegExp('模式', '標誌');

regex 是通用的變數名,用來保存正規表達式对象。例如:

const regex = /pattern/flags;

分別以regex當作變數,分別使用 literal notation 和constructor 寫法:

const regex = /ab+c/i; // literal notation
// OR
const regex = new RegExp("ab+c", "i"); // constructor with string pattern as first argument
// OR
const regex = new RegExp(/ab+c/, "i"); // constructor with regular expression literal as first argument

問題三、RegExp的兩種表達方式, literal notation和constructor是什麼?

  1. RegExp可以用兩種方式來表達:
    • literal notation 字面範本值
    • constructor 構造函數

以下程式碼分別將表達 literal notation和constructor:

const re = /ab+c/i;       // literal notation  字面範本值表達,i 表示不區分大小寫的匹配。

const re = new RegExp("ab+c", "i");    構造函數表達正規表達式,第一個參數用字串表達
// constructor with string pattern as first argument


const re = new RegExp(/ab+c/, "i");    構造函數表達正規表達式,第一個參數用正規表達式表達
// constructor with regular expression literal as first argument

使用構造函數時,需要遵循正常的字符串轉義規則(即在字符串中包含特殊字符時需要在符號的前面加上\),也就是斜線\前面的特殊字符,不會被以正規表達式特殊字符看待,而是以字串看待。

以下這兩個是相等的。

const re = /\w+/;

const re = new RegExp("\\w+");

註解:\w 在正規表達式中,意思為匹配大小寫文字letters (A–Z, a–z), 數字numbers (0–9), 和下底線underscore (__).

  • 字面範本值 literal notation:
// 使用字面值表示法創建一個正則表達式,匹配數字字符
const regexLiteral = /\d+/;

// 使用正則表達式進行匹配
const resultLiteral = regexLiteral.exec("12345");
console.log(resultLiteral); 
// 輸出: [ '12345', index: 0, input: '12345', groups: undefined ]
  • 構造函數 constructor:
// 使用RegExp構造函數創建一個正則表達式,匹配由變數決定的模式
const pattern = "\\d+"; // 匹配一個或多個數字字符的模式
const regexConstructor = new RegExp(pattern);

// 使用正則表達式進行匹配
const resultConstructor = regexConstructor.exec("12345");
console.log(resultConstructor); // 輸出: [ '12345', index: 0, input: '12345', groups: undefined ]

字面範本值在代碼解析期間編譯正則表達式,而RegExp構造函數允許在運行時編譯,並且可以根據變數值或運行時邏輯動態生成模式。有時候使用字面範本值 比構造函數效能高。

問題四、正規表達式有哪些?

  • \W
\W 不匹配: 數字,和字母(或混雜),和下底線。其他可以匹配

/judy7778999\W/.test("judy7778999**");      //true
  • \w
\w  匹配大小寫文字(A–Z, a–z), 數字(0–9), 和下底線(`__`)
/judy7778999\w/.test("judy7778999abcdA123_");           //true

  • \D
\D  只要不是數字,匹配大小寫字母、符號等等
/judy7778999\D/.test("judy7778999AAAAA");    //true
  • \d
\d   匹配任何數字,0-9
/\djudy7778999\D/.test("123judy7778999AAAAA");  //true
  • \S
\S 匹配任何不是空格的字母、數字、符號
/\Sjudy/.test("1234ABCjudy");       //true

  • \s
\s 匹配任何空格 
/\sjudy/.test("  judy");    //true
/\sjudy/.test("judy");      //false  因為judy前面沒有空格
  • .
. 任何文字、字母、數字、符號都可以
/judy\./.test("judy123");    //false 因為.前面不用加上反斜線

/../.test("😄"); // true; matches two UTF-16 code units as a surrogate pair
/../u.test("😄"); // false; input only has one Unicode character
  • \. 跳脫字元 這部分在書中3.3.2有提到
"\.judy\.";    //.judy.   
"\'judy\'";    //"'judy'"   雙引號內再加一組單引號

"\/judy\/";    //  '/judy/'
"\\judy\\";     //  '\\judy\\'

  • []
[] 中括號裡面的數字或文字才允許
/[1]/.test("1");       //true
/[1]/.test("123");     //true    只有1是相同的也匹配
  • []也可以這樣寫
註解: 以直列來看,T,H,B 一組、o, i, i一組、p, l, r一組、d自己一組
const a = ["Top", "Hill", "Bird" ];
/[B-T][i-o][i-r][d]/.test(a);         //true

寫成if else:
if(/[B-T][i-o][i-r][d]/.test(a)){
 console.log("Correct")
}else{
 console.log("Incorrect")
}

// Correct
  • [^abc] 匹配不包含a, b, c (三者皆不可以包含)
/[^123]/.test("456");     //true

  • ?
?  可以完全沒有,也可以有很多個       //quantifier 是指min:0  max:1
const pattern3 = /c?/;
console.log(text.match(pattern3)); // [""]

/happy1234567a?b?/.test("happy1234567acccbccccvvvbbb");     //true
/happy1234567a?b?/.test("happy1234567");    //true

+ 一個或是更多個

 +:匹配 b 1 次或多次          //quantifier+ 是指min:1  max:infinity(無限大)
const pattern2 = /b+/;
console.log(text.match(pattern2)); // ["bbbb"]

/happy123456+/.test('happy1234566');      //true  6後面有加了數字6
/happy123456+/.test('happy1234566');      
//true  6後面就算沒加,因為原本就有一個6了,所以符合+的條件(一個以上)

  • {m}
// {n,}:匹配 b 至少 2 次           //quantifier{n,}  min:2  max:infinity
const pattern5 = /b{2,}/;
console.log(text.match(pattern5)); // ["bbbb"]
  • {m,n}
{m,n}    {}前面字母重複次數的範圍
// {n,m}:匹配 c 1 到 3 次         //quantifier{min, max}  min:1  max:3
const pattern6 = /c{1,3}/;
console.log(text.match(pattern6)); // ["ccc"]

const b = ["happppppy", "happy"];
/hap{2,3}y/.test(b);              //true
  • *
const text = "aaaaabbbbcccc";

// *:匹配 a 0 次或多次           //quantifier* 是指min:0  max:infinity(無限大)
const pattern1 = /a*/;
console.log(text.match(pattern1)); // ["aaaaa"]

const c = ["abc", "abbbbc", "aabbccccc"];  匹配0次到多次都可以
/a*b*c*/.test(c);                           //true

問題五、RegExp輸出的方式有哪些?

  1. 在正規表達式(RegExp)中,pattern常常和 exec() 和test()方法連用。
  2. 在字串(String)中,常常和match(), matchAll(), replace(), replaceAll(), search(), split()連用。
  • 使用match來輸出符合格式的字串:
"happy12345678".match(/1234/);
//結果: ['1234', index: 5, input: 'happy12345678', groups: undefined]
  • 使用match輸出不符合格式的字串:
"happy12345678".match(/1234566/);
//結果: null
  • 使用test輸出符合格式的字串:
/happy12345678a*b*/.test("happy12345678aabb");    //true 
//正規表達式中,a* 代表a後面可以放大於1個a的字母、大於1個的b字母

/happy12345678a*b*/.test("happy12345678a11b22");   //true
//數字也可以放
  • 使用tset輸出不符合格式的字串:
/happy12345678/.test("1234567");      // false

未完待續~~~

Reference
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp
練習regex網站 : https://regexone.com/


上一篇
第三章 型別、值和變數-問題筆記 RegExp quantifier Disjunction ?:
下一篇
第三章 型別、值和變數-問題筆記 RegExp exec()
系列文
從0到有學習JavaScript31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言